package myRules;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;


import se.lth.eit.eit060.proj2.initiation.Utility;
import se.lth.eit.eit060.proj2.server.Logger;

public class Control {

	public HashMap<String, Record> records;
	public HashMap<String, Person> people;
	public Logger log;

	public Control() {
		records = new HashMap<String, Record>();
		people = new HashMap<String, Person>();
		log = new Logger();
		//loadPersons(Utility.PERSONFILE);
		addAll();
	}

	private void addAll() {
		Person p = new Person("John Smith", "LTH", Utility.Agent, "pass", "");
		people.put(p.getName(), p);
		Person p1 = new Person("Jan", "LTH2", Utility.Patient, "pass", "");
		people.put(p1.getName(), p1);
		Person p2 = new Person("Jen", "LTH", Utility.NURSE, "pass", "");
		people.put(p2.getName(), p2);
		Person p3 = new Person("Joe", "LTH2", Utility.DOCTOR, "pass", "");
		people.put(p3.getName(), p3);
		Person p4 = new Person("Nurse3", "LTH3", Utility.NURSE, "pass", "");
		people.put(p4.getName(), p4);
		Person p5 = new Person("Jen2", "LTH3", Utility.Agent, "pass", "");
		people.put(p5.getName(), p5);
		Person p6 = new Person("Nurse2", "LTH", Utility.NURSE, "pass", "");
		people.put(p6.getName(), p6);
		Person p7 = new Person("Nurse1", "LTH2", Utility.NURSE, "pass", "");
		people.put(p7.getName(), p7);
		Person p8 = new Person("Agent1", "LTH3", Utility.Agent, "pass", "");
		people.put(p8.getName(), p8);
		Person p9 = new Person("Bob", "LTH3", Utility.Patient, "pass", "");
		people.put(p9.getName(), p9);
		p.add(p1.getName());
		p2.add(p9.getName());
		Record r = new Record("LTH", "TEST1", "Record1 is legendary!");
		r.add(p.getName());
		r.add(p1.getName());
		r.add(p2.getName());
		r.add(p3.getName());
		Record r2 = new Record("LTH3", "TEST2", "Record2 is awesome!");
		r2.add(p.getName());
		r2.add(p2.getName());
		r2.add(p1.getName());
		records.put(r.getName(), r);
		records.put(r2.getName(), r2);
	}

	public void savePersons(String file) throws Exception {
		try {
			BufferedWriter BR = new BufferedWriter(
					new FileWriter(file));
			
			for (Person temp : people.values()) {
				System.out.println(temp);
				// konvertera till sepparerad sträng och skriv till fil.	
				BR.write(temp.getDivision() + Utility.SPLIT
						+ temp.getTitle() + Utility.SPLIT
						+ temp.getName()   + Utility.SPLIT 
						+ temp.getPassword() + Utility.SPLIT 
						+ temp.getPhone() + Utility.SPLIT  
						+ temp.getFailed());
				for(String s: temp){
					BR.write(Utility.SPLIT+s);
				}
				BR.write(log.n);
				// TODO: log this to logingsystem.
			}
			BR.close();
		} catch (Exception e) {
			// TODO add logging.
			e.printStackTrace();
		}
	}
	
	void printPersons()
	{
		for (Person temp : people.values()) {
			// konvertera till sepparerad sträng och skriv till fil.	
			System.out.println(temp.getDivision() + Utility.SPLIT
					+ temp.getTitle() + Utility.SPLIT
					+ temp.getName()   + Utility.SPLIT 
					+ temp.getPassword() + Utility.SPLIT 
					+ temp.getPhone() + Utility.SPLIT  
					+ temp.getFailed());
			// TODO: log this to logingsystem.
		}
	}
	
	protected void loadPersons(String File)
	{
		people = new HashMap<String, Person>();
		BufferedReader br=null;
		File f = new File(File);
		if(!f.exists()){
			try {
				f.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		try {
			br = new BufferedReader(new FileReader(File));
			String line = null;
			while ((line = br.readLine()) != null) {

				String[] values = line.split(Utility.SPLIT);
	//				public Person(String name, String divison, String title, String password, String phone,int failed)
				people.put(values[2], new Person(values[2],values[0],values[1],values[3],values[4],Integer.parseInt(values[5])));
				for(int i = 5;i<values.length;i++){
					people.get(values[2]).add(values[i]);
				}
			}
		} catch (FileNotFoundException ex) {
			ex.printStackTrace();
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			try {
				if (br != null)
					br.close();
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		Record r = new Record("LTH", "TEST1", "Record1 is legendary!");
		r.add("John Smith");
		r.add("Bob");
		r.add("Nurse1");
		r.add("Nurse2");
		Record r2 = new Record("LTH3", "TEST2", "Record2 is awesome!");
		//r2.add("John Smith");
		r2.add("Nurse3");
		r2.add("Agent1");
		r2.add("Unknown");
		records.put(r.getName(), r);
		records.put(r2.getName(), r2);
	}
	
	
	public String parse(String action, String name, String record, String text,
			String ip) {
		String[] recordings = record.split("<>");
		String password;
		if (recordings.length > 1) {
			password = recordings[1];
			record = recordings[0];
		} else {
			
			log.log(name, "Fails " + action, record, ip);
			return Utility.FULLWARNING;
		}
		System.out.println(action + " Name: " + name + " Record:" + record
				+ " Text: " + text);
		log.log(name, "Attempts " + action, record, ip);
		System.out.println(name);
		if (people.containsKey(name)) {
			Person p = people.get(name);
			System.out.println("Password: " +password);
			if(!p.comparePassword(password)){
				try {
					savePersons(Utility.PERSONFILE);
				} catch (Exception e) {
					e.printStackTrace();
				}
				log.log(name, "Failed login"+password+" " + action, record, ip);
				return Utility.WARNING+Utility.SPLIT+"Wrong password.";
			}
			try {
				savePersons(Utility.PERSONFILE);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (action.equals(Utility.DELETE)) {
				if (p.getTitle().equals(Utility.Agent)
						&& records.containsKey(record)) {
					records.remove(record);
					log.log(name, "SUCCESS " + action, record, ip);
					return Utility.SUCCESS + Utility.SPLIT + " DELETED";
				}
			}
			if (action.equals(Utility.CREATE)) {
				if (p.getTitle().equals(Utility.DOCTOR)) {
					Record r = createRecord(p, text);
					if (r != null) {
						records.put(r.getName(), r);
						log.log(name, "SUCCESS " + action, record, ip);
						return Utility.SUCCESS + Utility.SPLIT + " CREATED";
					}
				}
			}
			if (action.equals(Utility.READ)) {
				System.out.println("READ!2");
				Record r = records.get(record);
				if (r.contains(name)
						|| r.canRead(p.getTitle(), p.getDivision())
						|| p.getTitle().equals(Utility.Agent)) {
					log.log(name, "SUCCESS " + action, record, ip);
					return Utility.READ + Utility.SPLIT + r.read();
				}
			}
			if (action.equals(Utility.UPDATE)) {
				Record r = records.get(record);
				if (!(p.getTitle().equals(Utility.Patient) || p.getTitle()
						.equals(Utility.Agent))) {
					if (r.canWrite(name, p.getTitle(), p.getDivision(), text)) {
						log.log(name, "SUCCESS " + action, record, ip);
						return Utility.SUCCESS + Utility.SPLIT + " WRITTEN";
					}
				}
			}
			System.out.println("WHAZZ?");
			if (action.equals(Utility.LIST)) {
				String list = "";
				System.out.println("ListTest1");
				for (Record r : records.values()) {
					System.out.println("ListTest2");
					if (r.contains(name)
							|| r.canRead(p.getTitle(), p.getDivision())
							|| p.getTitle().equals(Utility.Agent)) {
						list += Utility.SPLIT + r.getName();
						System.out.println("ListTest3");
					}
				}
				log.log(name, "SUCCESS " + action, record, ip);
				return Utility.LIST + list;
			}
		}
		log.log(name, "Fails " + action, record, ip);
		return Utility.FULLWARNING;
	}

	// HOW TO CREATE A RECORD EXAMPLE. NEVER ADD A=<NAME> THERE NAME IS PATIENT!
	// Patient1
	// LTH
	// RECORDIA
	// A=John Smith
	// A=Nurse1
	// THIS IS AWESOME

	private Record createRecord(Person p, String text) {
		String[] temp = text.split(Utility.SPLIT);
		if (temp.length > 1) {
			String patient = temp[0];
			String division = temp[1];
			String name = temp[2];
			String data = "";
			if (!records.containsKey(name)) {
				HashSet<String> associates = new HashSet<String>();
				if (p.contains(patient)
						&& people.containsKey(patient)
						&& people.get(patient).getTitle().equals(
								Utility.Patient)) {
					for (int i = 3; i < temp.length; i++) {
						String[] split = temp[i].split("=");
						if (split.length > 1) {
							if (people.containsKey(split[1])
									&& !people.get(split[1]).getTitle().equals(
											Utility.Patient)) {
								associates.add(split[1]);
							}
						} else {
							data += temp[i];
						}
					}
					Record r = new Record(division, name, data);
					r.addAll(associates);
					r.add(patient);
					return r;
				}
			}
		}
		return null;
	}

}
